import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
import { createRouter, createWebHistory, createMemoryHistory } from 'vue-router'
import App from './App.vue'
import { isSubApp, setMainAppProps, getRouterMode } from '@/utils/qiankun'

let app = null
let container = null
let router = null
let history = null

// 完整的路由配置
const routes = [
  {
    path: '/',
    name: 'main-app-demo',
    component: () => import('./views/MainAppDataDemo.vue'),
    meta: {
      title: '主应用数据交互演示'
    }
  },
  {
    path: '/home',
    name: 'home',
    component: () => import('./views/HomeView.vue')
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('./views/AboutView.vue')
  },
]

/**
 * 渲染函数
 * @param {Object} props 主应用传递的属性
 * @returns
 */
function render(props = {}) {
  const { container: c } = props
  container = c || document.querySelector('#app')

  app = createApp(App)
  app.use(createPinia())
  app.use(ElementPlus)
  app.use(router)

  // 将主应用传递的数据挂载到全局
  if (props) {
    app.config.globalProperties.$mainProps = props
  }

  // 确保挂载到正确的容器
  if (container instanceof Element) {
    app.mount(container)
  } else {
    app.mount('#app')
  }

  console.log('子应用渲染完成', { container, props })
}

function createVueApp(props = {}) {
  // 保存主应用传递的 props
  setMainAppProps(props)
  
  // 根据环境选择路由模式
  if (isSubApp()) {
    // 子应用环境：使用 memory 路由
    history = createMemoryHistory(props.routerBase || '/sub-app2')
    console.log('[子应用2] 使用 Memory 路由模式，base:', props.routerBase || '/sub-app2')
    console.log('[子应用2] 接收到的 props:', props)
  } else {
    // 独立运行：使用 history 路由
    history = createWebHistory('/sub-app2')
    console.log('[子应用2] 独立运行，使用 History 路由模式')
  }

  router = createRouter({
    history,
    routes,
  })

  app = createApp(App)
  app.use(router)

  // 如果是子应用环境，添加全局属性方便组件访问
  if (isSubApp() && props) {
    app.config.globalProperties.$mainAppProps = props
    app.config.globalProperties.$mainAppData = props.mainAppData
    app.config.globalProperties.$globalActions = props.actions
    
    // 提供全局方法
    app.provide('mainAppProps', props)
    app.provide('mainAppData', props.mainAppData)
    app.provide('globalActions', props.actions)
    
    console.log('[子应用2] 已注入主应用数据到全局属性')
  }

  return app
}

// 独立运行时直接挂载
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  createVueApp().mount('#app')
  console.log('[子应用2] 独立运行模式启动完成')
}

// qiankun 环境下的生命周期
renderWithQiankun({
  // 子应用启动
  bootstrap() {
    console.log('[子应用2] 启动阶段')
  },

  // 子应用挂载
  mount(props) {
    console.log('[子应用2] 开始挂载，props:', props)
    
    const { container } = props
    const vueApp = createVueApp(props)
    
    // 挂载到指定容器
    vueApp.mount(container ? container.querySelector('#app') : '#app')
    
    console.log('[子应用2] 挂载完成')
    
    // 如果有全局状态，监听变化
    if (props.actions) {
      props.actions.onGlobalStateChange((state, prev) => {
        console.log('[子应用2] 全局状态变化:', { state, prev })
        
        // 处理路由变化
        if (state.subAppRoute !== prev.subAppRoute && state.currentSubApp === 'sub-app2') {
          const targetPath = state.subAppRoute || '/'
          if (router && router.currentRoute.value.path !== targetPath) {
            router.push(targetPath)
            console.log('[子应用2] 路由已同步:', targetPath)
          }
        }
      })
    }
  },

  // 子应用更新
  update(props) {
    console.log('[子应用2] 更新阶段，新的 props:', props)
    // 更新 props
    setMainAppProps(props)
  },

  // 子应用卸载
  unmount() {
    console.log('[子应用2] 开始卸载')
    
    if (app) {
      app.unmount()
      app = null
      router = null
      history = null
      console.log('[子应用2] 卸载完成')
    }
  },
})

// 导出 vite-plugin-qiankun 需要的生命周期钩子
export async function bootstrap() {
  console.log('子应用 bootstrap')
}

export async function mount(props) {
  console.log('子应用 mount', props)
  render(props)
}

export async function unmount(props) {
  console.log('子应用 unmount', props)
  if (app) {
    app.unmount()
    app = null
  }
  container = null
}
